www.gusucode.com > VC++ 实时监控系统所有的网络链接状态 > VC++ 实时监控系统所有的网络链接状态/gusucode/NetViewState/NetStateDlg.cpp

    //Download by http://www.NewXing.com
// NetStateDlg.cpp : implementation file
//

#include "stdafx.h"
#include "NetState.h"
#include "NetStateDlg.h"


#include "windows.h"
#include "stdio.h"
#include "snmp.h"
#include "winsock.h"

#define HOSTNAMELEN 256
#define PORTNAMELEN 256
#define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN

typedef struct _tcpinfo {
	struct _tcpinfo		*prev;
	struct _tcpinfo		*next;
	UINT				state;
	UINT				localip;
	UINT				localport;
	UINT				remoteip;
	UINT				remoteport;
} TCPINFO, *PTCPINFO;


typedef BOOL (__stdcall *func_SnmpExtensionInit)(
												 IN  DWORD               dwTimeZeroReference,
												 OUT HANDLE              *hPollForTrapEvent,
												 OUT AsnObjectIdentifier *supportedView);

typedef BOOL (__stdcall *func_SnmpExtensionQuery)(
												  IN BYTE                   requestType,
												  IN OUT RFC1157VarBindList *variableBindings,
												  OUT AsnInteger            *errorStatus,
												  OUT AsnInteger            *errorIndex);

func_SnmpExtensionInit	doSnmpExtensionInit = NULL;
func_SnmpExtensionQuery doSnmpExtensionQuery = NULL;

//
// Possible TCP endpoint states
//
static char TcpState[][32] = {
	"未知",
		"断开",
		"监听",
		"SYN发送",
		"SEN接受",
		"已连接",
		"FIN",//FIN等待
		"FIN2",//FIN_等待2
		"等待", //关闭等待
		"等待",//正在关闭
		"LAST_ACK",
		"等待"//TIME_WAIT
};

//
// Lists of endpoints
//
TCPINFO		TcpInfoTable;
TCPINFO		UdpInfoTable;
CString g_strShow;

//------------------------------------------------------------
//
// GetPortName
//
// Translate port numbers into their text equivalent if 
// there is one
//
//------------------------------------------------------------


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();
	
	// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA
	
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL
	
	// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNetStateDlg dialog

CNetStateDlg::CNetStateDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNetStateDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CNetStateDlg)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CNetStateDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CNetStateDlg)
	DDX_Control(pDX, IDC_NETSATE, m_listNetState);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CNetStateDlg, CDialog)
//{{AFX_MSG_MAP(CNetStateDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_SHOWNETSATE, OnShownetsate)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNetStateDlg message handlers

BOOL CNetStateDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	// Add "About..." menu item to system menu.
	
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CNetStateDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CNetStateDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting
		
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
		
		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		
		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CNetStateDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


/////////////////////////////////---------- 网络状态

char* CNetStateDlg::GetPortName( UINT port, char *proto, char *name, int namelen ) 
{
	struct servent* psrvent;
	
	if( psrvent = getservbyport( htons( (USHORT) port ), proto )) {
		
		strcpy( name, psrvent->s_name );
		
	} else {
		
		sprintf(name, "%d", port);
		
	}		
	return name;
}


//------------------------------------------------------------
//
// GetIpHostName
//
// Translate IP addresses into their name-resolved form
// if possible.
//
//------------------------------------------------------------
char* CNetStateDlg::GetIpHostName( BOOL local, UINT ipaddr, char *name, int namelen ) 
{
	struct hostent			*phostent;
	UINT					nipaddr;
	
	nipaddr = htonl( ipaddr );
	if( !ipaddr  ) {
		
		if( !local ) {
			
			sprintf( name, "%d.%d.%d.%d", 
				(nipaddr >> 24) & 0xFF,
				(nipaddr >> 16) & 0xFF,
				(nipaddr >> 8) & 0xFF,
				(nipaddr) & 0xFF);
			
		} else {
			
			gethostname(name, namelen);
		}
		
	} else if( ipaddr == 0x0100007f ) {
		
		if( local ) {
			
			gethostname(name, namelen);
		} else {
			
			strcpy( name, "localhost" );
		}
		
	} else if( phostent = gethostbyaddr( (char *) &ipaddr,
		sizeof( nipaddr ), PF_INET )) {
		
		strcpy( name, phostent->h_name );
		
	} else {
		
		sprintf( name, "%d.%d.%d.%d", 
			(nipaddr >> 24) & 0xFF,
			(nipaddr >> 16) & 0xFF,
			(nipaddr >> 8) & 0xFF,
			(nipaddr) & 0xFF);
	}
	return name;
}


//------------------------------------------------------------
//
// LoadInetMibEntryPoints
//
// Load the TCP/IP SNMP extension DLL and locate the entry
// points we will use.
//
//------------------------------------------------------------
BOOLEAN CNetStateDlg::LoadInetMibEntryPoints()
{
	HINSTANCE	hInetLib;
	
	if( !(hInetLib = LoadLibrary( "inetmib1.dll" ))) {
		
		return FALSE;
	}
	
	if( !(doSnmpExtensionInit = (func_SnmpExtensionInit) GetProcAddress( hInetLib, "SnmpExtensionInit" )) ) 
	{
		
		return FALSE;
	}
	
	if( !(doSnmpExtensionQuery = (func_SnmpExtensionQuery) GetProcAddress( hInetLib, "SnmpExtensionQuery" )) ) 
	{
		
		return FALSE;
	}
	
	return TRUE;
}

/*
//------------------------------------------------------------
//
// Main
//
// Do it all. Load and initialize the SNMP extension DLL and
// then build a table of TCP endpoints and UDP endpoints. After
// each table is built resolve addresses to names and print
// out the information
//
//------------------------------------------------------------
int main( int argc, char *argv[] )
{

  return 0;
  }
  
*/

void CNetStateDlg::OnCancel() 
{
	CDialog::OnCancel();
}

void CNetStateDlg::Shownetsate() 
{

	m_listNetState.ResetContent();
	
	HANDLE					hTrapEvent;
	AsnObjectIdentifier		hIdentifier;
	RFC1157VarBindList		bindList;
	RFC1157VarBind			bindEntry;
	UINT					tcpidentifiers[] = { 1,3,6,1,2,1,6,13,1,1};
	UINT					udpidentifiers[] = { 1,3,6,1,2,1,7,5,1,1};
	AsnInteger				errorStatus, errorIndex;
	TCPINFO					*currentEntry, *newEntry;
	UINT					currentIndex;
	WORD					wVersionRequested;
	WSADATA					wsaData;
	char					/*localname[HOSTNAMELEN],*/ remotename[HOSTNAMELEN];
	char					remoteport[PORTNAMELEN], localport[PORTNAMELEN];
	char					localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN];
	
	//
	// Initialize winsock
	//
	wVersionRequested = MAKEWORD( 1, 1 );
	if( WSAStartup(  wVersionRequested, &wsaData ) ) {
		
		MessageBox("Could not initialize Winsock.\n");
		return ;
	}
	
	//
	// Locate and initialize INETMIB1
	//
	if( !LoadInetMibEntryPoints()) {
		
		MessageBox("Could not load extension DLL.\n");
		return ;
	}
	
	if( !doSnmpExtensionInit( GetCurrentTime(), &hTrapEvent, &hIdentifier )) {
		
		MessageBox("Could not initialize extension DLL.\n");
		return ;
	}
	
	//
	// Initialize the query structure once
	//
	bindEntry.name.idLength = 0xA;
	bindEntry.name.ids = tcpidentifiers;
	bindList.list = &bindEntry;
	bindList.len  = 1;
	
	TcpInfoTable.prev = &TcpInfoTable;
	TcpInfoTable.next = &TcpInfoTable;
	
	//
	// Roll through TCP connections
	//
	currentIndex = 1;
	currentEntry = &TcpInfoTable;
	while(1) {
		
		if( !doSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
			&bindList, &errorStatus, &errorIndex )) {
			
			return ;
		}
		
		//
		// Terminate when we're no longer seeing TCP information
		//
		if( bindEntry.name.idLength < 0xA ) break;
		
		//
		// Go back to start of table if we're reading info
		// about the next byte
		//
		if( currentIndex != bindEntry.name.ids[9] ) {
			
			currentEntry = TcpInfoTable.next;
			currentIndex = bindEntry.name.ids[9];
		}
		
		//
		// Build our TCP information table 
		//
		switch( bindEntry.name.ids[9] ) {
			
		case 1:
			
			//
			// Always allocate a new structure
			//
			newEntry = (TCPINFO *) malloc( sizeof(TCPINFO ));
			newEntry->prev = currentEntry;
			newEntry->next = &TcpInfoTable;
			currentEntry->next = newEntry;
			currentEntry = newEntry;
			
			currentEntry->state = bindEntry.value.asnValue.number;
			break;
			
		case 2:
			
			currentEntry->localip = 
				*(UINT *) bindEntry.value.asnValue.address.stream;
			currentEntry = currentEntry->next;
			break;
			
		case 3:
			
			currentEntry->localport = 
				bindEntry.value.asnValue.number;
			currentEntry = currentEntry->next;
			break;
			
		case 4:
			
			currentEntry->remoteip = 
				*(UINT *) bindEntry.value.asnValue.address.stream;
			currentEntry = currentEntry->next;
			break;
			
		case 5:
			
			currentEntry->remoteport = 
				bindEntry.value.asnValue.number;
			currentEntry = currentEntry->next;
			break;
		}
		
	}
	
	//
	// Now print the connection information
	//
	g_strShow.Format("%-15s %-20s %-35s %s\n", "[协议]", "[本地端口]", "[远程地址]", "[状态]" );
	m_listNetState.AddString(g_strShow);
	
	currentEntry = TcpInfoTable.next;
	while( currentEntry != &TcpInfoTable ) {
		
		/*
		sprintf( localaddr, "%s:%s", 
			GetIpHostName( TRUE, currentEntry->localip, localname, HOSTNAMELEN), 
			GetPortName( currentEntry->localport, "tcp", localport, PORTNAMELEN ));
		*/
		g_strShow.Format("%d", currentEntry->localport);
		if (GetPortName( currentEntry->localport, "tcp", localport, PORTNAMELEN ) == g_strShow)
		{//不加说明
			sprintf( localaddr, "%d", currentEntry->localport);	
		}
		else
		{
			sprintf( localaddr, "%d:%s", currentEntry->localport,
			GetPortName( currentEntry->localport, "tcp", localport, PORTNAMELEN ));
		}

		sprintf( remoteaddr, "%s:%s",
			GetIpHostName( FALSE, currentEntry->remoteip, remotename, HOSTNAMELEN), 
			currentEntry->remoteip ? 
			GetPortName( currentEntry->remoteport, "tcp", remoteport, PORTNAMELEN ):
		"0" );
		
		g_strShow.Format("%-16s %-20s %-35s %s\n", "TCP", 
			localaddr, remoteaddr,
			TcpState[currentEntry->state]);
		m_listNetState.AddString(g_strShow);
		
		currentEntry = currentEntry->next;
	}
	printf("\n");
	
	//
	// Initialize the query structure once
	//
	bindEntry.name.idLength = 0xA;
	bindEntry.name.ids = udpidentifiers;
	bindList.list = &bindEntry;
	bindList.len  = 1;
	
	UdpInfoTable.prev = &UdpInfoTable;
	UdpInfoTable.next = &UdpInfoTable;
	
	//
	// Roll through UDP endpoints
	//
	currentIndex = 1;
	currentEntry = &UdpInfoTable;
	while(1) {
		
		if( !doSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
			&bindList, &errorStatus, &errorIndex )) {
			
			return ;
		}
		
		//
		// Terminate when we're no longer seeing TCP information
		//
		if( bindEntry.name.idLength < 0xA ) break;
		
		//
		// Go back to start of table if we're reading info
		// about the next byte
		//
		if( currentIndex != bindEntry.name.ids[9] ) {
			
			currentEntry = UdpInfoTable.next;
			currentIndex = bindEntry.name.ids[9];
		}
		
		//
		// Build our TCP information table 
		//
		switch( bindEntry.name.ids[9] ) {
			
		case 1:
			
			//
			// Always allocate a new structure
			//
			newEntry = (TCPINFO *) malloc( sizeof(TCPINFO ));
			newEntry->prev = currentEntry;
			newEntry->next = &UdpInfoTable;
			currentEntry->next = newEntry;
			currentEntry = newEntry;
			
			currentEntry->localip = 
				*(UINT *) bindEntry.value.asnValue.address.stream;
			break;
			
		case 2:
			
			currentEntry->localport = 
				bindEntry.value.asnValue.number;
			currentEntry = currentEntry->next;
			break;
		}
	}
	
	//
	// Now print the connection information
	//
	currentEntry = UdpInfoTable.next;
	while( currentEntry != &UdpInfoTable ) {
	/*	
		g_strShow.Format("%7s %s:%s\n", "UDP",
			GetIpHostName( TRUE, currentEntry->localip, localname, HOSTNAMELEN), 
			GetPortName( currentEntry->localport, "udp", localport, PORTNAMELEN ) );
	*/	
		//"%-15s %-20s %-35s %s\n"
		g_strShow.Format("%d", currentEntry->localport);
		if (GetPortName( currentEntry->localport, "udp", localport, PORTNAMELEN )== g_strShow)
		{//不加说明
			g_strShow.Format("%-16s %d\n", "UDP",
			currentEntry->localport);
		}
		else
		{
			g_strShow.Format("%-16s %d:%s\n", "UDP",
			currentEntry->localport,
			GetPortName( currentEntry->localport, "udp", localport, PORTNAMELEN ) );
		}

		m_listNetState.AddString(g_strShow);
		
		currentEntry = currentEntry->next;
	}
	//列举完毕
	MessageBeep(-1);
}
void CNetStateDlg::OnShownetsate() 
{
	AfxBeginThread(EnumNetState, this);
}


//列举线程
UINT EnumNetState(LPVOID pParam)
{
	//Sleep(1000);
	CNetStateDlg* DLG = (CNetStateDlg*) pParam;
	DLG->Shownetsate();
	return 0;
}